import axios from 'axios'
import router from '@/router/index'
import { useUserStore } from '@/stores'
import { ElMessage, ElMessageBox, ElLoadingService } from 'element-plus'
import { isBlob, getLocale } from '@/utils'

const Code = {
  /** 请求成功 */
  SUCCESS: 200,
  /** 认证失败 */
  AUTH_FAILD: 401,
  /** 无访问权限 */
  NOACCESS: 403,
  /** 未找到资源 */
  NOTFOUND: 404,
  /** 请求方法错误 */
  METHOD_ERROR: 405,
  /** 服务器错误 */
  SERVER_ERROR: 500
}

let isShow = true,
  loadingInstance = null,
  /** 请求次数 */
  reqCounter = 0

function closeLoading() {
  reqCounter--
  if (reqCounter <= 0) {
    loadingInstance?.close()
  }
}

axios.defaults.baseURL = import.meta.env.VITE_API_SUFFIX

// 数据类型
axios.defaults.headers.post['Content-Type'] = 'application/json'

// 请求超时时间（ms）
axios.defaults.timeout = 1000 * 60

// 请求拦截器
axios.interceptors.request.use(
  config => {
    loadingInstance = ElLoadingService({
      background: 'transparent'
    })
    reqCounter++
    if (config.headers) {
      const userStore = useUserStore()
      config.headers.Authorization = userStore.token
      config.headers['Accept-Language'] = normalHttpLocale(getLocale())
    }
    return config
  },
  error => {
    closeLoading()
    console.dir('request error: ', error)

    return Promise.reject(error)
  }
)

// 响应拦截器
axios.interceptors.response.use(
  response => {
    closeLoading()
    const { data } = response

    switch (data.code) {
      case Code.SUCCESS:
        return data
      case Code.AUTH_FAILD:
        unauthorized()
        return Promise.reject(response)
      default:
        console.log('response default : ', response)
        if (isBlob(data)) {
          return response
        }

        ElMessage({
          message: data.msg ?? '系统异常',
          type: 'error',
          duration: 3000
        })
        return Promise.reject(response)
    }
  },
  error => {
    closeLoading()
    if (!error) {
      ElMessage({
        message: '请求异常',
        type: 'error',
        duration: 5000
      })
      return Promise.reject()
    }
    console.dir('response error: ', error)

    const { response } = error

    if (!response) {
      ElMessage({
        message: '请求未响应',
        type: 'error',
        duration: 5000
      })
      return Promise.reject()
    }

    switch (response.status) {
      case Code.AUTH_FAILD:
        unauthorized()

        break
      case Code.NOACCESS:
        ElMessage.error(response.data.msg + ' 没有访问权限')
        break
      case Code.NOTFOUND: //=>找不到页面
        ElMessage.error(response.config.url + ' 方法不存在')
        break
      case Code.METHOD_ERROR:
        ElMessage.error('请求方法错误 ' + response.statusText)
        break
      case Code.SERVER_ERROR: //=>找不到页面
        ElMessage({
          message: '服务器错误 ' + response.statusText,
          type: 'error',
          duration: 5000,
          showClose: true
        })
        break
      case 504: //=>超时
        ElMessage({
          message: '网关超时 ' + response.statusText,
          type: 'error',
          duration: 5000,
          showClose: true
        })
        break
      default:
        //=>以上都不是
        ElMessage({
          message: '服务器错误 ' + response.statusText,
          type: 'error',
          duration: 5000,
          showClose: true
        })
        break
    }
    return Promise.reject(error)
  }
)

export async function unauthorized() {
  if (!isShow) {
    return
  }
  isShow = false
  try {
    await ElMessageBox.alert('登录信息过期，请重新登录', '温馨提示', {
      confirmButtonText: '知道了'
    })
  } finally {
    isShow = true
    router.push('/login')
  }
}

const localeMap = {
  'zh-cn': 'zh-cn',
  'zh-tw': 'zh-tw',
  en: 'en'
}

function normalHttpLocale(lang) {
  return localeMap[lang] ?? 'zh-cn,zh;q=0.9'
}

export const service = axios
